import os
from datetime import datetime

from django.contrib.auth.decorators import login_required
from django.http import HttpResponse
from django.shortcuts import redirect, render
from django.urls import reverse
from django.utils.decorators import method_decorator
from django.views import View

from demo1.forms import ArticleForms
from demo1.models import Article, Classes
from django_study.settings import MEDIA_ROOT


# data = {
#     "python": [
#         {
#             'title': '【Python】NumPy（一）：数据类型、创建数组及基本操作',
#             'desc': '本篇介绍了什么是numpy，以及numpy中的数据类型，如何使用NumPy来创建数组，创建数组的7种方式，以及数组的一些基本操作。',
#             'detail': 'https://blog.csdn.net/zhyhgx/article/details/143017888?spm=1001.2100.3001.7377&utm_medium=distribute.pc_feed_blog_category.none-task-blog-classify_tag-1-143017888-null-null.nonecase&depth_1-utm_source=distribute.pc_feed_blog_category.none-task-blog-classify_tag-1-143017888-null-null.nonecase',
#             'img': 'https://i-blog.csdnimg.cn/direct/6d114b5e0e634c7c8b29aacd1483d0ad.png?x-oss-process=image/resize,m_fixed,h_300,image/format,png',
#             'create_time': datetime(2024, 10, 8, 15, 16)
#         },
#         {
#             'title': 'Python酷库之旅-第三方库Pandas(181)',
#             'desc': '第三方库Pandas(181)',
#             'detail': 'https://blog.csdn.net/ygb_1024/article/details/143352388?spm=1001.2100.3001.7377&utm_medium=distribute.pc_feed_blog_category.none-task-blog-classify_tag-3-143352388-null-null.nonecase&depth_1-utm_source=distribute.pc_feed_blog_category.none-task-blog-classify_tag-3-143352388-null-null.nonecase',
#             'img': 'https://img-blog.csdnimg.cn/img_convert/fad536e972e14ce4b37803185dc3b00c.png?x-oss-process=image/resize,m_fixed,h_300,image/format,png',
#             'create_time': datetime(2024, 11, 8, 15, 16)
#         },
#         {
#             'title': 'python安卓自动化pyaibote实践------学习通自动刷课',
#             'desc': 'pyaibote安卓自动化实战，学习通刷课脚本',
#             'detail': 'https://blog.csdn.net/2302_79590880/article/details/138360025?spm=1001.2100.3001.7377&utm_medium=distribute.pc_feed_blog_category.none-task-blog-classify_tag-4-138360025-null-null.nonecase&depth_1-utm_source=distribute.pc_feed_blog_category.none-task-blog-classify_tag-4-138360025-null-null.nonecase',
#             'img': 'https://img-blog.csdnimg.cn/direct/e5914924856742b8a8be94f4b60deb6d.jpeg?x-oss-process=image/resize,m_fixed,h_300,image/format,png',
#             'create_time': datetime(2024, 11, 8, 6, 16)
#         }],
#     "java": [
#         {
#             'title': '【JavaSE】【多线程】线程池',
#             'desc': '线程池',
#             'detail': 'https://blog.csdn.net/yj20040627/article/details/143282442?spm=1001.2100.3001.7377&utm_medium=distribute.pc_feed_blog_category.none-task-blog-classify_tag-1-143282442-null-null.nonecase&depth_1-utm_source=distribute.pc_feed_blog_category.none-task-blog-classify_tag-1-143282442-null-null.nonecase',
#             'img': 'https://i-blog.csdnimg.cn/direct/ddc6897d72474fb1ba598f55e0027dee.png?x-oss-process=image/resize,m_fixed,h_300,image/format,png',
#             'create_time': datetime(2024, 11, 8, 10, 16)
#         },
#         {
#             'title': 'Java 多线程（三）—— 死锁',
#             'desc': 'Java 死锁问题与解决方案',
#             'detail': 'https://blog.csdn.net/liwuqianhzc/article/details/142959410?spm=1001.2100.3001.7377&utm_medium=distribute.pc_feed_blog_category.none-task-blog-classify_tag-3-142959410-null-null.nonecase&depth_1-utm_source=distribute.pc_feed_blog_category.none-task-blog-classify_tag-3-142959410-null-null.nonecase',
#             'img': 'https://i-blog.csdnimg.cn/direct/95e9053a24f542eb8c5abe55d5f153fe.png?x-oss-process=image/resize,m_fixed,h_300,image/format,png',
#             'create_time': datetime(2024, 9, 8, 15, 16)
#         },
#         {
#             'title': '【JavaSE】【多线程】volatile,wait/notify',
#             'desc': 'volatile处理内存可见性问题wait / notify调控线程调度',
#             'detail': 'https://blog.csdn.net/yj20040627/article/details/142694133?spm=1001.2100.3001.7377&utm_medium=distribute.pc_feed_blog_category.none-task-blog-classify_tag-5-142694133-null-null.nonecase&depth_1-utm_source=distribute.pc_feed_blog_category.none-task-blog-classify_tag-5-142694133-null-null.nonecase',
#             'img': 'https://i-blog.csdnimg.cn/direct/46687258a85941fbabcada13902e1d88.png?x-oss-process=image/resize,m_fixed,h_300,image/format,png',
#             'create_time': datetime(2024, 11, 1, 15, 16)
#         }],
#     'ai': []
# }


def test(request, **kwargs):
    username = request.user.username
    classes = kwargs.get('nav')
    try:
        data = Classes.objects.get(name=classes)
    except Classes.DoesNotExist:
        return redirect('not_fount')
    return HttpResponse(render(request, 'demo/demo.html', context={
        'res': data.article_set.all(),
        'dd': Classes.objects.all(),
        'data': classes,
        'username': username
    }))


def test1(request):
    return HttpResponse('页面找不到了~~~')


def index(request):
    username = request.user.username
    return HttpResponse(render(request, 'demo/index.html', context={
        'dd': Classes.objects.all(),
        'username': username
    }))


class AddArticleView(View):
    @method_decorator(login_required)
    def get(self, request):
        form = ArticleForms()
        return render(request, 'demo/add_artcle.html', {'username': request.user.username, 'form': form})

    def post(self, request):
        # post请求方式提交的数据request.POST 类字典结构数据
        # 获取数据
        form = ArticleForms(request.POST, request.FILES)  # 文件数据会保存到请求对象的FILES属性
        # 校验数据
        if form.is_valid():
            # 对通过校验的数据进行处理，持久化
            title = form.cleaned_data.get('title')
            desc = form.cleaned_data.get('desc')
            content = form.cleaned_data.get('content')

            cover = form.cleaned_data.get('cover')

            user = request.user

            classes = form.cleaned_data.get('classes')
            labels = form.cleaned_data.get('label')  # QuerySet
            # 图片本身是保存在服务器上面，数据库保存的是这个图片的所在地址
            # 把上传的图片写到服务器上面，保存
            file_name = f'{datetime.now().strftime("%Y%m%d%H%M%S")}_{cover.name}'  # 时间_上传的文件名
            with open(os.path.join(MEDIA_ROOT, file_name), 'wb') as fp:
                for data in cover.chunks():  # 上传的文件数据划分批次
                    fp.write(data)

            # 持久化到数据库中
            article = Article.objects.create(title=title, desc=desc, content=content, cover=file_name, user=user,
                                             classes=classes)

            # 多对多，已有数据的绑定
            for i in labels:
                article.label.add(i)

        # return render(request, 'demo/add_artcle.html', {'username': request.user.username, 'form': form})
        return redirect(reverse('index'))


class ArticleDetail(View):
    # 显示某篇文章的详情内容 还需要文章的id来确认是显示那一篇文章
    def get(self, request, id):
        try:
            article = Article.objects.get(id=id)
        except Article.DoesNotExist:
            return redirect('not_find')
        return render(request, 'demo/article_detail.html',
                      {'article': article,
                       'labels': article.label.all(),
                       'username': request.user.username
                       })


class ArticleUser(View):
    @method_decorator(login_required)
    def get(self, request):
        article = Article.objects.filter(user=request.user)
        print(article)
        return render(request, 'demo/user_article.html', {'username': request.user.username, 'articles': article})


class ArticleUpdate(View):
    @method_decorator(login_required)
    def get(self, request, id):
        try:
            article = Article.objects.get(id=id)
        except Article.DoesNotExist:
            return redirect('not_find')
        # 没有报错，有文章的情况下，定义一个字典保存修改之前的文章数据
        data = {
            "title": article.title,
            "desc": article.desc,
            "content": article.content,
            "classes": article.classes,
            "label": article.label.all()
        }
        form = ArticleForms(data)
        return render(request, 'demo/update_article.html', {'username': request.user.username, 'form': form})

    def post(self, request, id):
        form = ArticleForms(request.POST, request.FILES)
        username = request.user.username
        if form.is_valid():
            print('通过校验')
            title = form.cleaned_data.get('title')
            desc = form.cleaned_data.get('desc')
            content = form.cleaned_data.get('content')
            # 文件数据保存到数据库里面的应该是图片的地址，图片本身放到服务器
            cover = form.cleaned_data.get('cover')
            user = request.user
            classes = form.cleaned_data.get('classes')
            labels = form.cleaned_data.get('label')
            # 文件名 不能直接用上传的文件名来进行取名
            file_name = f'{datetime.now().strftime("%Y%m%d%H%M%S")}_{cover.name}'
            # open第一个参数为文件的地址，第二个参数为文件的打开模式
            with open(os.path.join(MEDIA_ROOT, file_name), 'wb') as fp:
                # cover.chunks对文件数据进行迭代并且产生给定大小的块
                for data in cover.chunks():
                    fp.write(data)
            articles = Article.objects.filter(id=id)
            os.remove(os.path.join(MEDIA_ROOT, articles[0].cover))
            article = articles.update(title=title, desc=desc, content=content, cover=file_name, user=user,
                                      classes=classes)
            articles[0].label.clear()
            #     多对多数据绑定
            for i in labels:
                articles[0].label.add(i)

        return redirect('ArticleUser')


class ArticleDelete(View):
    def get(self, request, id):
        try:
            article = Article.objects.get(id=id)
        except Article.DoesNotExist:
            return redirect('not_find')
        os.remove(os.path.join(MEDIA_ROOT, article.cover))
        article.delete()
        return redirect('ArticleUser')